package server;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

import org.omg.CORBA.portable.IndirectionException;


public class Mappa implements Serializable{
	
	public static String nomefile = "MappaProva.txt";
	public static int RIGHE_MAPPA = 40;
	public static int COLONNE_MAPPA = 40;
	public static final char CODICE_ACQUA = 'a';
	public static final char CODICE_TERRA_SEMPLICE = 't';
	public static final char CODICE_TERRA_VEGETAZIONE = 'v';
	public static final char CODICE_TERRA_CAROGNA = 'c';
	public static final double PERC_A = 0.2;
	public static final double PERC_T = 0.8;
	private char[][] caselleInChar;
	private Casella[][] caselle;
	
	public Mappa(String nomefile,int r,int c){
		Mappa.nomefile=nomefile;
		RIGHE_MAPPA=r;
		COLONNE_MAPPA=c;
		estraiMappaCaratteriDaFile();
		creaCaselleDaChar();
	}
	
	public Mappa(){
		creaMappaCaratteriCasuale();
		creaCaselleDaChar();
	}
	
	//---------GETTERS AND SETTERS------------------------------------------
	
	public Casella[][] getCaselle() {
		return caselle;
	}

	public void setCaselle(Casella[][] caselle) {
		this.caselle = caselle;
	}
	
	public char[][] getCaselleInChar() {
		return caselleInChar;
	}

	public void setCaselleInChar(char[][] caselleInChar) {
		this.caselleInChar = caselleInChar;
	}

	//---------METODI-------------------------------------------------------
	
	//estrae dal file la mappa in forma di matrice di caratteri
	private void estraiMappaCaratteriDaFile(){
		char[][] MatriceMappaChar = new char [RIGHE_MAPPA][COLONNE_MAPPA];
		int next;
		char nextc;
		
		try{
			FileReader cursore= new FileReader(nomefile);
			for(int i=0;i<RIGHE_MAPPA;i++){
				if(i>0){
					cursore.skip(2);//per saltare i caratteri \n e \r presenti alla fine di ogni riga
				}
				for(int j=0;j<COLONNE_MAPPA;j++){
					next=cursore.read();
					nextc=(char) next; 
					MatriceMappaChar[i][j]=nextc;
				}
			}
			cursore.close();
		}
		catch(FileNotFoundException e){
			System.out.println("File non trovato");	  
		}
		catch (IOException e){
			System.out.println("Errore in lettura del file");
		}
		caselleInChar=MatriceMappaChar;
	}
	
	
	//crea casualmente la mappa in forma di matrice di caratteri
	
	private void creaMappaCaratteriCasuale(){
		
		RIGHE_MAPPA=40;
		COLONNE_MAPPA=40;
		final int numMinCelleA= 5;
		final int numMaxCelleA = 15;
				
		Random gen = new Random();
		
		int indiceX;
		int indiceY;
		
		char[][] MatriceMappaChar = new char [RIGHE_MAPPA][COLONNE_MAPPA];
		
		//inizializzazione della matriceMappaChar
		for(int i=0;i<RIGHE_MAPPA;i++){
				for(int j=0;j<COLONNE_MAPPA;j++){
					MatriceMappaChar[i][j]='.';
				}
			}
				
		//creazione contorno mappa con acqua
		for(int i=0;i<RIGHE_MAPPA;i++){
			for(int j=0;j<COLONNE_MAPPA;j++){
				if( (i==0 || i==RIGHE_MAPPA-1))
					MatriceMappaChar[i][j]='a';
				if( (j==0 || j==RIGHE_MAPPA-1))
					MatriceMappaChar[i][j]='a';
			}
		}
		
		int x=0,y=0, xPrec=0, yPrec=0;
		int numcelleA=0;			//indica quante celle riempire di acqua nel quadrato 5x5 (min=5 - max=15)
		int contatoreCelleA=0;    	//indica il num di celle riempiete di un quadrato 5x5
		int contatoreCelleATot=0;	//indica num di celle totali nella mappa riempite con acqua
		int spostamentoX=0;
		int spostamentoY=0;
			
		ArrayList<Posizione> punti = new ArrayList<Posizione>();	//contiene tutte le posizioni di riferimento dei 36 quadrati 5x5
			
		int z=0;
		int v=0;
	
		//inizializzazione ArrayList con le 36 posizioni di riferimento
		for(z=0;z<36;z=z+6){
			for(v=0;v<36;v=v+6){
				punti.add(new Posizione(z+2,v+2));
			}
		}
			
		int s=0;
		do{
			numcelleA=gen.nextInt(numMaxCelleA-numMinCelleA+1)+numMinCelleA;
			contatoreCelleA=0;
				
			indiceX=punti.get(s).getX();	//indiceX indica coordinata X del punto di riferimento de quadrato s-esimo 5x5
			indiceY=punti.get(s).getY();	//indiceY indica coordinata Y del punto di riferimento de quadrato s-esimo 5x5
			
			do{
				if(contatoreCelleA==0){		 //riempio di acqua una cella per la prima volta nel quadrato 5x5	
					x=indiceX+gen.nextInt(5);//coordinate x e y della prima cella 
					y=indiceY+gen.nextInt(5);//da riempire con 'a' nel quadrato 5x5 in esame
				}
				else{
					xPrec=x;
					yPrec=y;
					spostamentoX=gen.nextInt(3)-1;//se =0 la x non cambia (xPrec=x); se=-1 mi sposto a sx (xPrec-1); se=1 mi sposto a dx (xPrec+1)
					spostamentoY=gen.nextInt(3)-1;//se =0 la y non cambia (yPrec=y); se=-1 mi sposto in su (y=yPrec-1): se =1 mi sposto in giu (yPrec=y+1)
									
					//controlli sulla x per non uscire dal quadrato 5x5
					if(spostamentoX==0){
						xPrec=x;
					}
					if(spostamentoX==-1){
						if(xPrec>indiceX)
							x=xPrec-1;
					}
					if(spostamentoX==1){
						if(xPrec<indiceX+4)
							x=xPrec+1;
					}
					
					//controlli sulla y per non uscire dal quadrato 5x5
					if(spostamentoY==0){
						yPrec=y;
					}
					if(spostamentoY==-1){
						if(yPrec>indiceY)
							y=yPrec-1;
					}
					if(spostamentoY==1){
						if(yPrec<indiceY+4)
							y=yPrec+1;
					}
					
				}
			
				//riempio la cella con acqua nel caso non sia gia presente dell acqua	
				if(MatriceMappaChar[y][x]!='a'){
					MatriceMappaChar[y][x]='a';
					contatoreCelleA++;
					contatoreCelleATot++;
				}
			
			}while(contatoreCelleA<numcelleA && contatoreCelleATot<( RIGHE_MAPPA*COLONNE_MAPPA*PERC_A));
			s++;
		
		}while( contatoreCelleATot<( RIGHE_MAPPA*COLONNE_MAPPA*PERC_A) && s<punti.size() );
	
		
		//riempo caselle non contenenti acqua con terra (80%)
		int contatoreCelleTTot=0;
		
		for(int i=0;i<RIGHE_MAPPA;i++){
			for(int j=0;j<COLONNE_MAPPA;j++){
				if(MatriceMappaChar[i][j]!='a'){
					MatriceMappaChar[i][j]='t';
					contatoreCelleTTot++;
				}
			}
		}
		
		//riempo con caselle vegetazione (40% di quelle terra)
		int numCaselleV=(int)((RIGHE_MAPPA*COLONNE_MAPPA-contatoreCelleATot)*0.4);
		int contatoreCelleVTot=0;
		int numCaselleC=20;
		int contatoreCelleCTot=0;
		int a;
		int b;
		
		do{
			a=gen.nextInt(RIGHE_MAPPA);
			b=gen.nextInt(COLONNE_MAPPA);
			if(MatriceMappaChar[a][b]=='t'){
				MatriceMappaChar[a][b]='v';
				contatoreCelleVTot++;
				contatoreCelleTTot--;
			}	
		}while(contatoreCelleVTot<numCaselleV);
		
		//riempo con caselle carogna (20)
		do{
			a=gen.nextInt(RIGHE_MAPPA);
			b=gen.nextInt(COLONNE_MAPPA);
			if(MatriceMappaChar[a][b]=='t'){
				MatriceMappaChar[a][b]='c';
				contatoreCelleCTot++;
				contatoreCelleTTot--;
			}	
		}while(contatoreCelleCTot<numCaselleC);
		
		/*
		//inizio test: stampa MatriceMappaChar
		for(int i=0;i<RIGHE_MAPPA;i++){
			for(int j=0;j<COLONNE_MAPPA;j++){
				System.out.print(" "+MatriceMappaChar[i][j]);
				
			}
			System.out.println("");
		}
		
		//fine test
		*/
		
		caselleInChar=MatriceMappaChar;
	}
	
	
	//trasforma la matrice di caratteri in matrice di caselle
	private void creaCaselleDaChar(){
		int numeroCasuale;
		Random generatore = new Random();
		Casella[][] caselleCreate = new Casella[RIGHE_MAPPA][COLONNE_MAPPA];
		for(int i=0;i<RIGHE_MAPPA;i++){
			for(int j=0;j<COLONNE_MAPPA;j++){
				if(caselleInChar[i][j]==CODICE_ACQUA){
					caselleCreate[i][j]= new Acqua();
				}
				if(caselleInChar[i][j]==CODICE_TERRA_SEMPLICE){
					caselleCreate[i][j]= new TerraSemplice();
				}
				if(caselleInChar[i][j]==CODICE_TERRA_VEGETAZIONE){
					numeroCasuale=generatore.nextInt(201)+150;// 250+-40%
					caselleCreate[i][j]= new TerraVegetazione(numeroCasuale);
				}
				if(caselleInChar[i][j]==CODICE_TERRA_CAROGNA){
					numeroCasuale=generatore.nextInt(301)+350;//500+-30%
					caselleCreate[i][j]= new TerraCarogna(numeroCasuale);
				}
			}
		}
		caselle=caselleCreate;
	}
	
}